// trdpcommunicator.cpp
#include "trdpcommunicator.h"
#include <QThread>
#include <QDebug>
#include <QApplication>

UINT32 ipToUint(const std::string& ipStr) {
    unsigned int ip[4];
    if (sscanf(ipStr.c_str(), "%u.%u.%u.%u", &ip[3], &ip[2], &ip[1], &ip[0]) < 4) {
        return 0;
    }
    return (ip[3] << 24) | (ip[2] << 16) | (ip[1] << 8) | ip[0];
}

void usage(const char* appName) {
    std::cout << "Usage: " << appName << " [options]" << std::endl;
    std::cout << "TRDP sender and receiver combined application" << std::endl;
    std::cout << "Options:" << std::endl;
    std::cout << "  -o <own IP>          Set own IP address (default: 0.0.0.0)" << std::endl;
    std::cout << "  -p <comId,ip,interval>  Add publisher (multiple allowed)" << std::endl;
    std::cout << "                        Example: -p 1,192.168.1.100,1000000" << std::endl;
    std::cout << "  -s <comId[,multicast]>  Add subscriber (multiple allowed)" << std::endl;
    std::cout << "                        Example: -s 1,224.0.0.1" << std::endl;
    std::cout << "  -v                   Print version and exit" << std::endl;
    std::cout << "  -h                   Show this help" << std::endl;
}



TrdpCommunicator::TrdpCommunicator(QObject *parent)
    : QObject(parent), m_trdpHandler(nullptr), m_running(false), m_eventThread(nullptr) {
}

TrdpCommunicator::~TrdpCommunicator() {
    stop();
}

bool TrdpCommunicator::start(const QString& ownIp, const QString& remoteIp,
                             const std::map<UINT32, UINT32>& publishers,
                             const std::vector<UINT32>& subscribers) {
    // 如果已经在运行，则先停止
    if (m_running) {
        stop();
    }

    m_trdpHandler = new TRDPHandler();

    // 初始化TRDP
    if (!m_trdpHandler->init()) {
        qWarning() << "TRDP初始化失败";
        delete m_trdpHandler;
        m_trdpHandler = nullptr;
        return false;
    }

    // 转换IP地址格式
    UINT32 ownIpUint = ipToUint(ownIp.toStdString());
    UINT32 remoteIpUint = ipToUint(remoteIp.toStdString());

    // 打开会话
    if (!m_trdpHandler->openSession(ownIpUint)) {
        qWarning() << "TRDP会话打开失败";
        delete m_trdpHandler;
        m_trdpHandler = nullptr;
        return false;
    }

    // 设置发布者
    for (const auto& pub : publishers) {
        UINT32 comId = pub.first;
        UINT32 interval = pub.second;
        if (!m_trdpHandler->publish(comId, remoteIpUint, interval)) {
            qWarning() << "发布COMID" << comId << "失败";
            stop();
            return false;
        }
    }

    // 设置订阅者
    for (UINT32 comId : subscribers) {
        if (!m_trdpHandler->subscribe(comId)) {
            qWarning() << "订阅COMID" << comId << "失败";
            stop();
            return false;
        }
    }

    // 更新会话
    if (!m_trdpHandler->updateSession()) {
        qWarning() << "TRDP会话更新失败";
        stop();
        return false;
    }

    // 1. 创建线程前，确保之前的线程指针已清空
    Q_ASSERT(m_eventThread == nullptr);

    // 2. 创建新线程
    m_eventThread = new QThread(this); // 注意：这里将this作为父对象，简化内存管理
    if (!m_eventThread) {
        qCritical() << "Failed to create QThread instance.";
        // 清理已分配的TRDP资源
        delete m_trdpHandler;
        m_trdpHandler = nullptr;
        return false;
    }

    // 3. 移动当前对象到新线程
    moveToThread(m_eventThread);

    // 4. 连接信号和槽
    // 使用QueuedConnection确保线程安全，虽然对于started信号不是必须的，但这是个好习惯
    connect(m_eventThread, &QThread::started, this, &TrdpCommunicator::processEvents, Qt::QueuedConnection);
    connect(m_eventThread, &QThread::finished, this, &TrdpCommunicator::onThreadFinished);

    // 5. 启动线程
    m_eventThread->start();
    m_running = true;

    return true;
}

void TrdpCommunicator::stop() {

    if (!m_running) {
        return;
    }
    m_running = false;

    // 安全地停止线程
    if (m_eventThread) {
        // 如果线程正在运行，请求其退出
        if (m_eventThread->isRunning()) {
            m_eventThread->quit();
            // 等待线程结束，超时时间可以根据需要调整
            if (!m_eventThread->wait(5000)) {
                qWarning() << "Thread did not finish in time. Forcing termination.";
                m_eventThread->terminate();
                m_eventThread->wait();
            }
        }
        // 此时线程已经结束，可以安全地删除
        delete m_eventThread;
        m_eventThread = nullptr; // 关键：将指针置为nullptr
    }

    // 清理TRDP资源
    if (m_trdpHandler) {
        delete m_trdpHandler;
        m_trdpHandler = nullptr;
    }

    // 将对象移回主线程，以便下次可以正常start
    if (thread() != QApplication::instance()->thread()) {
        moveToThread(QApplication::instance()->thread());
    }
}

void TrdpCommunicator::sendData(UINT32 comId, const QByteArray& data) {
    if (!m_trdpHandler) {
        qWarning() << "TRDP未初始化，无法发送数据";
        return;
    }

    m_trdpHandler->sendData(comId, std::string(data.constData(), data.size()));
}

void TrdpCommunicator::processEvents() {
    while (m_running && m_trdpHandler) {
        m_trdpHandler->processEvents();

        // 检查接收的数据
        for (const auto& sub : m_trdpHandler->getSubscribers()) {
            UINT32 comId = sub.first;
            TRDP_PD_INFO_T pdInfo;
            UINT8 buffer[DATA_MAX];
            UINT32 bufferSize = DATA_MAX;

            if (m_trdpHandler->receiveData(comId, pdInfo, buffer, bufferSize) && bufferSize > 0) {
                QByteArray data(reinterpret_cast<char*>(buffer), bufferSize);
                emit dataReceived(data, comId);
            }
        }

        // 短暂休眠，避免CPU占用过高
        QThread::msleep(10);
    }
}

// 新增的槽函数，在线程结束时被调用
void TrdpCommunicator::onThreadFinished() {
    // 这个槽函数会在m_eventThread线程结束后被调用
    // 可以在这里进行一些清理工作
    qDebug() << "TRDP event thread has finished.";
}
